from django.shortcuts import render


# Create your views here.

from rest_framework.views import APIView
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response

from user.models import UserModel, ThirdPartyAuth
from user.ser import (
    RegisterSerializer,
    EmailSerializer,
    SmsLoginSerializer,
    PasswordLoginSerializer,
    SfUserSerializer,
    ThirdPartyAuthSerializer,
)

import re, requests, json, hashlib, time, random
from django.conf import settings
from django_redis import get_redis_connection
from rest_framework.permissions import IsAuthenticated

from mycerlery.sms.tasks import send_sms
from tools.myjwt import mjwt
from dingxiang.utils.ronglianyunapi import send_message
from urllib.parse import quote

# ================================================ 钉钉第三方登录 ================================================

# class DingTalkLogin(APIView):
#     def get(self, request):

#         params = [
#             f"redirect_uri={quote('http://127.0.0.1:8080/dingtalkcallback/')}",
#             "response_type=code",
#             "client_id=dingstqta9m1sphood0c",
#             "scope=openid",
#             "prompt=consent"
#         ]
#         url = "https://login.dingtalk.com/oauth2/auth?" + ("&".join(params))
#         return Response({"url": url})

# class DingTalkCallback(APIView):
#     def get(self, request):
#         authCode = request.query_params.get('code')

#         # 根据authCode获取用户accessToken
#         data = {
#             "clientId": "dingstqta9m1sphood0c",
#             "clientSecret": "-ryMdeXTuDUKvzRoTLiAgT1zdyIuFLr_OpIikkAP5rXur_lO70a1TaZGFEbz_rl4",
#             "code": authCode,
#             "grantType": "authorization_code"
#         }
#         resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
#         accessToken = resp.get('accessToken')

#         # 根据accessToken获取用户信息
#         headers = {"x-acs-dingtalk-access-token": accessToken}
#         resp = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
     
#         name = resp.get('nick')
#         uid = resp.get('openId')
#         phone = resp.get('mobile')

#         # 登录，写入三方登录表和用户表
#         sfl = ThirdPartyAuth.objects.filter(uid=uid, type=1).first()
#         if not sfl:
#             # 写入用户表
#             # 手机号用户存在直接绑定,不存在注册新用户
#             user = UserModel.objects.filter(phone=phone).first()
#             if not user:
#                 userinfo = {
#                     "name": name,
#                     "phone": phone,
#                     "password": phone,
#                     "username": phone
#                 }
#                 us = SfUserSerializer(data=userinfo)
#                 if us.is_valid():
#                     user = us.save()
#                 else:
#                     return Response({"code": 10001, "msg": us.errors})
#             # 写入三方登录表
#             sfinfo = {
#                 "type": 1,
#                 "token": accessToken,
#                 "uid": uid,
#                 "userid": user.id
#             }
#             sfs = ThirdPartyAuthSerializer(data=sfinfo)
#             if sfs.is_valid():
#                 sfs.save()
#             else:
#                 return Response({"code": 10001, "msg": sfs.errors})
#         else:
#             user = sfl.userid
#             sfl.token = accessToken
#             sfl.save()

#         # 生成jwt token并返回前端
#         payload = {"userid": user.id, "username": user.username, "exp": int(time.time()) + 60 * 60 * 2}
#         token = mjwt.jwt_encode(payload)
#         payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
#         refreshToken = mjwt.jwt_encode(payload)
#         query = [f"userid={payload['userid']}", f"username={payload['username']}", f"token={token}",
#                  f"refreshToken={refreshToken}"]
#         return Response({"code":200,"token":token})

from tools.SFLogin import factory

class DingTalkLogin(APIView):
    def get(self, request):
        type=request.query_params.get('type')
        product=factory.create_product(type)
        return Response({'code':200, 'data':product.geturl(), 'msg':'success'})  
    # product.geturl()
from rest_framework.response import Response
from rest_framework import status

class DingTalkCallback(APIView):
    def get(self, request):
        authCode = request.query_params.get('authCode')
        type = request.query_params.get('type')
        product = factory.create_product(type)
        data = product.callback(authCode=authCode)
        return data

# ================================================ 测试短信发送 ================================================

# 测试短信发送视图，用于创建用户
class CreateUserViews(APIView):
    def get(self,request):
        # 测试celery调用
        datas = (
            '9834',
            '1'
        )
        res = send_sms.delay('1','18201275696',datas)

# ================================================ 处理发送短信验证码逻辑 ================================================

# 处理发送短信验证码的逻辑

class SmsApiView(APIView):
    def get(self,request,phone):
        print(phone)
        # -------------------redis:短信验证码------------------
        # 获取redis的连接
        redis = get_redis_connection('sms_code')
        # 获取redis中,手机号验证码60秒发送间隔,是否过期
        res_interval = redis.ttl(f"interval_{phone}")
        # 如果等于-2  表示数据过期
        if res_interval != -2:
            return Response({'message':'验证码还在有效期内,请勿频繁发送验证码', 'status':'400'})
        elif res_interval == -2:
            return Response({'message':'验证码超过有效期', 'status':'200'})
        
        # -------------------redis:短信验证码------------------


        # 获取容联云配置信息
        ronglianyun = settings.RONGLIANYUN

        # 获取短信模板
        tid = ronglianyun.get('reg_tid')
        
        # 获取过期时间
        sms_expire = ronglianyun.get('sms_expire')
        
        # 获取发送间隔
        sms_interval = ronglianyun.get('sms_interval')

        # 生成验证码，格式化操作，不足4位，前面补0
        code = f'{random.randint(0,999999):04d}'
        
        # 配置文件中秒位单位，容联云以分钟位单位
        interval = sms_interval/60
        
        # 基本发送短信完成
        # 如何存储验证码
        # 生成发送短信的datas
        datas = (code, interval)
        print(datas)

        # 调用celery执行短信发送任务
        send_sms.delay(tid,phone,datas)

        # -------------------redis:短信验证码------------------

        # redis写入验证码, reids 提供了 简单事务
        # 开启事务和管道,优化redis写入,一次性将所有指令发送给redis
        pipe = redis.pipeline()
        
        #开启redis事务,保证所有命令 正确执行
        pipe.multi()
        redis.setex(f"sms_{phone}",sms_expire,code)
        
        # 短信发送的间隔时间
        redis.setex(f"interval_{phone}",sms_interval,'-')
        
        # 提交事务,把暂存在pipeline对象中多条命令,一次性提交给reids
        pipe.execute()
        
        # -------------------redis:短信验证码------------------
        
        # return Response({'message':'短信发送成功...', 'status':'200'})

# ================================================ 手机号注册 ================================================

# CreateApiView  :序列化器中实现业务逻辑判断
# 序列化器：序列化：orm模型对象转成json格式的字符串……和反序列化将json格式得字符串转成模型对象
# 数据校验
# 保存数据
class RegisterViews(CreateAPIView):
    queryset = UserModel.objects.all()
    serializer_class = RegisterSerializer

# ================================================ 邮箱注册 ================================================

# CreateApiView  :序列化器中实现业务逻辑判断
# 序列化器：序列化：orm模型对象转成json格式的字符串……和反序列化将json格式得字符串转成模型对象
# 数据校验
# 保存数据
class EmailViews(CreateAPIView):
    queryset = UserModel.objects.all()
    serializer_class = EmailSerializer

# ================================================ 短信登录 ================================================

class SmsLoginView(APIView):
    def post(self, request):
        serializer = SmsLoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data
            # 这里我们假设serializer已经处理了token的生成和保存
            return Response({"token": user['token'], "refresh": user['refresh'], 'status':'200'})
        return Response({'message':"短信登录失败,请检查手机号和验证码", 'status':'400'})

# ================================================ 密码登录 ================================================

class PasswordLoginView(APIView):
    def post(self, request):
        serializer = PasswordLoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data
            # 这里我们假设serializer已经处理了token的生成和保存
            return Response({"token": user['token'], "refresh": user['refresh'], 'status':'200'})
        return Response({'message':"密码登录失败,请检查用户名和密码", 'status':'400'})

# ================================================ 手机号唯一判断 ================================================

class PhoneApiView(APIView):
    def get(self,request,phone):
        try:
            user = UserModel.objects.get(phone__exact=phone)
            return Response({'message':"手机号已经存在,请登录或者修改密码", 'status':'400'})
        except UserModel.DoesNotExist:
            return Response({'message':"手机号可以注册", 'status':'200'})

# ================================================ 邮箱唯一判断 ================================================

class EmailApiView(APIView):
    def get(self,request,email):
        try:
            email = UserModel.objects.get(email__exact=email)
            return Response({'message':"邮箱已经存在,请登录或者修改密码", 'status':'400'})
        except UserModel.DoesNotExist:
            return Response({'message':"邮箱可以注册", 'status':'200'})
